<?php

namespace PKFrame;
defined('PATH_PK') or die();

use PKFrame\DataHandler\Arrays;
use PKFrame\DataHandler\Numbers;

interface interface_Service
{
    public function interface_getEntityById($id, $viewField = '*');
}

abstract class Service extends Base implements interface_Service
{
    protected $path_sql;
    protected $moduleName = '';
    protected static $db;

    public function __construct()
    {
        !empty($this->moduleName) ?: $this->moduleName = request()->module();
        $this->path_sql = path_app($this->moduleName) . 'SQL' . DS;
    }

    abstract protected function db();

    abstract public function GetList($viewParams = [], $viewField = '*');

    abstract public function GetEntity($viewParams = [], $viewField = '*');

    final protected function getEntityById($id, $tips_idEmpty, $tips_entityEmpty, $viewField = '*')
    {
        try {
            if (!Numbers::IsId($id)) {
                throw new \Exception($tips_idEmpty);
            }
            $entity = $this->GetEntity(['id' => $id], $viewField = '*');
            if (empty($entity)) {
                throw new \Exception($tips_entityEmpty);
            }
            return $entity;
        } catch (\Exception $e) {
            request()->isAjax()
                ? $this->noticeByJson($e->getMessage(), $this->moduleName)
                : $this->noticeByPage($e->getMessage(), null, $this->moduleName);
        }
        return null;
    }

    final public function Add(array $data = [])
    {
        return $this->db()->Insert($data)->Exec();
    }

    final public function BatchInsert(array $data = [], string $table_name = null)
    {
        !Arrays::Is($data) ?: $this->db()->Insert($data, $table_name, true)->Exec();
    }

    final public function Update(array $updateWhere = [], array $data = [])
    {
        $this->db()->Where($updateWhere)->Update($data)->Exec();
    }

    final public function UpdateById($id, array $data = [])
    {
        if (!is_array($id)) {
            Numbers::IsId($id) ?: $this->noticeByJson('update data by id is 0');
        }
        $this->Update(['id' => $id], $data);
    }

    final public function Drop($params = [])
    {
        $this->db()->Where($params)->Delete()->Exec();
    }

    final public function DeleteById($id)
    {
        $this->Drop(['id' => $id]);
    }

    final public function HideById($id)
    {
        $this->UpdateById($id, ['isDeleted' => 1]);
    }

    final public function HideByParams(array $params)
    {
        $this->Update($params, ['isDeleted' => 1]);
    }

    final public function GetSQLFile(string $name_file, $search, $replace): string
    {
        $sql_from = fileHelper()->GetContentsByDisk($this->path_sql . $name_file . '.sql',
            'SQL file name: ' . $name_file . '  Cannot be found or does not exist');
        is_array($search) ?: $search = '[' . $search . ']';
        return str_replace($search, $replace, $sql_from);
    }

    final public function Truncate()
    {
        $this->db()->Truncate()->Exec();
    }

}